import datetime

from django.db import models
from django.db.models import Max, Sum

from base.models import Employee, AccountTitle, CustomSupplier
from users.models import UserInfo

TYPES = (
    (0, '银行账号'),
    (1, '现金账号'),
    (2, '其他'),

)

DEFAULT = (
        (0, '否'),
        (1, '是'),
    )


class CapitalAccount(models.Model):
    """资金账号"""

    name = models.CharField(verbose_name='收款账号', max_length=32)
    account_type = models.IntegerField(verbose_name='账号类型', blank=True, null=True, choices=TYPES)
    bank = models.CharField(verbose_name='银行名称', max_length=32, blank=True, null=True)
    account = models.CharField(verbose_name='银行账号', max_length=32, blank=True, null=True)
    init_money = models.FloatField(verbose_name='初始资金', blank=True, null=True, default=0)
    balance = models.FloatField(verbose_name='余额', blank=True, null=True)
    default = models.IntegerField(verbose_name='默认账号', choices=DEFAULT, blank=True, null=True)
    update_time = models.DateTimeField(verbose_name='修改时间', auto_now=True)
    add_time = models.DateTimeField(verbose_name='添加时间', auto_now_add=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = '资金账号'
        verbose_name_plural = verbose_name
        ordering = ["-id"]


class HistoryAccount(models.Model):
    """历史账号"""
    name = models.CharField(verbose_name='收款账号', max_length=32)
    account_type = models.IntegerField(verbose_name='账号类型', blank=True, null=True, choices=TYPES)
    bank = models.CharField(verbose_name='银行名称', max_length=32, blank=True, null=True)
    account = models.CharField(verbose_name='银行账号', max_length=32, blank=True, null=True)
    init_money = models.FloatField(verbose_name='初始资金', blank=True, null=True, default=0)
    money = models.FloatField(verbose_name='当前交易金额', blank=True, null=True)
    balance = models.FloatField(verbose_name='余额', blank=True, null=True)
    default = models.IntegerField(verbose_name='默认账号', choices=DEFAULT, blank=True, null=True)
    update_time = models.DateTimeField(verbose_name='修改时间', auto_now=True)
    add_time = models.DateTimeField(verbose_name='添加时间', auto_now_add=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = '资金账号'
        verbose_name_plural = verbose_name
        ordering = ["-id"]


class FundBill(models.Model):
    """资金账单(主)"""
    CATEGORY = (
        (0, '费用'),
        (1, '收入'),
        (2, '借入'),
        (3, '借出'),
    )
    VERIFY = (
        (0, '未通过'),
        (1, '通过'),
    )
    order_no = models.CharField(verbose_name='单号', max_length=24, blank=True, null=True)
    employee = models.ForeignKey(Employee, verbose_name='姓名', related_name="bills", on_delete=models.DO_NOTHING, null=True, db_constraint=False)
    acc_title = models.ForeignKey(AccountTitle, verbose_name='科目', on_delete=models.SET_NULL, null=True, db_constraint=False)
    account = models.ForeignKey(CapitalAccount, verbose_name='资金账号', on_delete=models.DO_NOTHING, null=True, blank=True,
                                db_constraint=False)
    money = models.FloatField(verbose_name='金额', default=0, blank=True, null=True)
    repayment = models.FloatField(verbose_name='还款金额', default=0, blank=True, null=True)
    order_time = models.DateField(verbose_name='时间', blank=True, null=True)
    category = models.IntegerField(verbose_name='类型', blank=True, null=True, choices=CATEGORY)
    desc = models.CharField(verbose_name='备注', max_length=100, blank=True, null=True)
    source = models.CharField(verbose_name='来源', max_length=100, blank=True, null=True)
    user = models.ForeignKey(UserInfo, verbose_name='经手人', blank=True, null=True, on_delete=models.SET_NULL, db_constraint=False)
    verify = models.IntegerField(verbose_name='审核', blank=True, null=True, choices=VERIFY)
    balance = models.FloatField(verbose_name='余额', blank=True, null=True)
    update_at = models.DateTimeField(verbose_name='修改时间', auto_now=True)
    create_at = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)

    def __str__(self):
        return self.order_no

    class Meta:
        verbose_name = '资金账单'
        verbose_name_plural = verbose_name
        ordering = ["-create_at"]

    @classmethod
    def get_max_code(cls, category):
        # 费用单
        if category == 0:
            year = datetime.datetime.now().strftime('FYD%Y%m%d')
        # 其他收入单
        elif category == 1:
            year = datetime.datetime.now().strftime('QTSR%Y%m%d')
        # 借入
        elif category == 2:
            year = datetime.datetime.now().strftime('ZJJR%Y%m%d')
        # 借出
        elif category == 3:
            year = datetime.datetime.now().strftime('ZJJC%Y%m%d')
        else:
            year = datetime.datetime.now().strftime('FYD%Y%m%d')

        max_code = cls.objects.filter(order_no__startswith=year).aggregate(max_code=Max("order_no"))
        max_value = max_code['max_code']
        if max_value is None:
            num = '0001'
            code = '{0}{1}'.format(year, num)
            return code
        else:
            num = str(int(max_value[-4:]) + 1).rjust(4, '0')
            code = '{0}{1}'.format(year, num)
            return code

    def get_repayment(self):
        results = self.repayments.all().aggregate(total_money=Sum('money'))
        return results.get('total_money') or 0

    def save(self, *args, **kwargs):
        if not self.order_no:
            order_no = self.__class__.get_max_code(self.category)
            self.order_no = order_no
        return super().save(*args, **kwargs)


class RepaymentBill(models.Model):
    """还款记录"""
    order_no = models.CharField(verbose_name='单号', max_length=24, blank=True, null=True)
    bill = models.ForeignKey(FundBill, verbose_name='借入借出', related_name='repayments', on_delete=models.CASCADE, blank=True, null=True, db_constraint=False)
    bill_date = models.DateField(verbose_name='还款时间', blank=True, null=True)
    money = models.FloatField(verbose_name='还款金额', blank=True, null=True)
    desc = models.CharField(verbose_name='备注', max_length=100, blank=True, null=True)
    user = models.ForeignKey(UserInfo, verbose_name='经手人', blank=True, null=True, on_delete=models.SET_NULL)
    update_at = models.DateTimeField(verbose_name='修改时间', auto_now=True)
    create_at = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)

    def __str__(self):
        return self.order_no

    class Meta:
        verbose_name = '还款记录'
        verbose_name_plural = verbose_name
        ordering = ["-create_at"]

    @classmethod
    def get_max_code(cls):
        year = datetime.datetime.now().strftime('HKDJ%Y%m%d')
        max_code = cls.objects.filter(order_no__startswith=year).aggregate(max_code=Max("order_no"))
        max_value = max_code['max_code']
        if max_value is None:
            num = '0001'
            code = '{0}{1}'.format(year, num)
            return code
        else:
            num = str(int(max_value[-4:]) + 1).rjust(4, '0')
            code = '{0}{1}'.format(year, num)
            return code

    def save(self, *args, **kwargs):
        if not self.order_no:
            order_no = self.__class__.get_max_code()
            self.order_no = order_no
        return super().save(*args, **kwargs)


class Journal(models.Model):
    """流水账"""
    order_no = models.CharField(verbose_name='单据号', max_length=24, blank=True, null=True)
    order_time = models.DateTimeField(verbose_name='单据日期', blank=True, null=True)
    customer = models.ForeignKey(CustomSupplier, verbose_name="客户名称", on_delete=models.DO_NOTHING, blank=True, null=True, db_constraint=False)
    name = models.CharField(verbose_name='姓名', max_length=24, blank=True, null=True)
    account = models.ForeignKey(CapitalAccount, verbose_name='银行账号', on_delete=models.DO_NOTHING, null=True, db_constraint=False)
    # oper_type = models.CharField(verbose_name="操作类型", blank=True, null=True, max_length=128)
    money = models.FloatField(verbose_name='发生金额', blank=True, null=True)
    balance = models.FloatField(verbose_name='余额', blank=True, null=True)
    source = models.CharField(verbose_name="单据来源", null=True, max_length=128)
    desc = models.CharField(verbose_name='备注', max_length=100, blank=True, null=True)
    user = models.ForeignKey(UserInfo, verbose_name='录入人', blank=True, null=True, on_delete=models.SET_NULL, db_constraint=False)
    update_at = models.DateTimeField(verbose_name='修改时间', auto_now=True)
    create_at = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)

    def __str__(self):
        return self.order_no

    class Meta:
        verbose_name = '流水账'
        verbose_name_plural = verbose_name
        ordering = ["create_at"]


class Prepayment(models.Model):
    """预收款"""
    STATUS = (
        (0, '收款标识'),
        (1, '抵扣标识'),
    )
    code = models.CharField(verbose_name='收入单编号', max_length=24, blank=True, null=True)
    order_time = models.DateTimeField(verbose_name='收款时间', blank=True, null=True)
    customer = models.ForeignKey(to=CustomSupplier, verbose_name='付款客户', blank=True, null=True,
                                 on_delete=models.SET_NULL, db_constraint=False)
    user = models.ForeignKey(to=UserInfo, verbose_name='收款员', blank=True, null=True, on_delete=models.SET_NULL, db_constraint=False)
    amount = models.FloatField(verbose_name='收款金额', blank=True, null=True)
    deduct_amount = models.FloatField(verbose_name='抵扣金额', blank=True, null=True)
    flag = models.IntegerField(verbose_name='收款状态', blank=True, null=True, choices=STATUS)
    account = models.ForeignKey(to=CapitalAccount, verbose_name='资金账号', on_delete=models.SET_NULL, blank=True,
                                null=True, db_constraint=False)
    remark = models.CharField(verbose_name='备注', max_length=128, blank=True, null=True)
    oper_user = models.ForeignKey(to=UserInfo, verbose_name='操作员', related_name="prepay_users", blank=True, null=True,
                                  on_delete=models.SET_NULL, db_constraint=False)

    update_at = models.DateTimeField(verbose_name='修改时间', auto_now=True)
    create_at = models.DateTimeField(verbose_name='添加时间', auto_now_add=True)

    def __str__(self):
        return self.code

    class Meta:
        verbose_name = '预收款'
        verbose_name_plural = verbose_name
        ordering = ["id"]

    @classmethod
    def get_max_code(cls, flag):
        date = datetime.datetime.now().strftime('%Y%m%d')

        if flag == 0:  # 预付款
            date = "YFK{}".format(date)

        max_code = cls.objects.filter(code__startswith=date).aggregate(max_code=Max("code"))
        max_value = max_code['max_code']

        if max_value is None:
            num = '0001'
            code = '{0}{1}'.format(date, num)
            return code
        else:
            num = str(int(max_value[-4:]) + 1).rjust(4, '0')
            code = '{0}{1}'.format(date, num)
            return code

    def save(self, *args, **kwargs):
        if self.code == "" or self.code is None:
            self.code = self.__class__.get_max_code(self.flag)
        else:
            if self.id is None:
                exists = self.__class__.objects.filter(code=self.code).exists()
                if exists:
                    self.code = self.__class__.get_max_code(self.flag)

        return super().save(*args, **kwargs)
